<template>
  <template v-if="searchBoxItem.type === 'input'">
    <el-input
      class="form-item-base"
      v-model="componentSearchForm[searchBoxItem.field]"
      type="text"
      :placeholder="searchBoxItem.placeholder || '请输入'"
      @input="handleInputChange"
      :clearable="searchBoxItem.clearable === false ? false : true"
      :disabled="searchBoxItem?.disabled ?? false"
      :style="searchBoxItem.style"
    >
    </el-input>
  </template>
  <template v-else-if="searchBoxItem.type === 'textarea'">
    <el-input
      type="textarea"
      v-model="componentSearchForm[searchBoxItem.field]"
      :placeholder="searchBoxItem.placeholder || '请输入'"
      @input="handleInputChange"
      maxlength="255"
      show-word-limit
      resize="none"
      :style="searchBoxItem.style"
      :disabled="searchBoxItem?.disabled ?? false"
    />
  </template>

  <template v-if="searchBoxItem.type === 'input-unit'">
    <el-input
      class="form-item-base"
      v-model="componentSearchForm[searchBoxItem.field]"
      :placeholder="searchBoxItem.placeholder || '请输入'"
      @input="handleInputChange"
      :clearable="searchBoxItem.clearable === false ? false : true"
      :disabled="searchBoxItem?.disabled ?? false"
      :style="searchBoxItem.style"
      maxlength="19"
      v-positive-only:6
      type="number"
      @wheel.stop.prevent
    >
      <template #append>
        <CSelect v-model="componentSearchForm[searchBoxItem.unitField]" style="width: 120px">
          <el-option
            :label="item.label"
            :value="item.value"
            v-for="item in getOptions(searchBoxItem)"
            :key="item.value"
          ></el-option>
        </CSelect>
      </template>
    </el-input>
  </template>
  <template v-else-if="searchBoxItem.type === 'radio'">
    <el-radio-group
      v-model="componentSearchForm[searchBoxItem.field]"
      :disabled="searchBoxItem?.disabled ?? false"
      @change="handleSelectChange"
    >
      <el-radio
        v-for="(item, index) in getOptions(searchBoxItem)"
        :key="index"
        :label="searchBoxItem.valueField ? item[searchBoxItem.valueField] : item.value"
      >
        {{ item.label }}</el-radio
      >
    </el-radio-group>
  </template>
  <template v-else-if="searchBoxItem.type === 'standardRadio'">
    <CStandardRadioGroup
      v-model="componentSearchForm[searchBoxItem.field]"
      @change="handleUploadChange"
    >
      <CStandardRadio
        v-for="item in getOptions(searchBoxItem)"
        :label="item.label"
        :desc="item.desc"
        :value="item.value"
        :key="item.value"
      ></CStandardRadio>
    </CStandardRadioGroup>
  </template>
  <template v-else-if="searchBoxItem.type === 'checkbox'">
    <el-checkbox-group
      @change="handleSelectChange"
      v-model="componentSearchForm[searchBoxItem.field]"
      :disabled="searchBoxItem?.disabled ?? false"
    >
      <el-checkbox
        v-for="item in getOptions(searchBoxItem)"
        :key="item.value"
        :label="searchBoxItem.valueField ? item[searchBoxItem.valueField] : item.value"
      >
        {{ item.label }}</el-checkbox
      >
    </el-checkbox-group>
  </template>
  <template v-else-if="searchBoxItem.type === 'select'">
    <CSelect
      size="default"
      class="form-item-base header-select"
      v-model="componentSearchForm[searchBoxItem.field]"
      :placeholder="searchBoxItem.placeholder || '请选择'"
      :filterable="searchBoxItem.filterable || false"
      v-bind="handleBind(searchBoxItem)"
      @change="handleSelectChange"
      :clearable="searchBoxItem.clearable === false ? false : true"
      :prop-options="getOptions(searchBoxItem)"
      @visible-change="handleVisibleChange($event, searchBoxItem)"
      :style="searchBoxItem.style"
      :disabled="searchBoxItem?.disabled ?? false"
    >
      <template #suffix v-if="Object.keys(handleBind(searchBoxItem)).includes('remote')">
        <CIcon class="header-select--remote-icon" type="c-xian-sousuo"></CIcon>
      </template>
      <el-option
        v-for="(item, index) in getOptions(searchBoxItem)"
        :key="index"
        :value="searchBoxItem.valueField ? item[searchBoxItem.valueField] : item.value"
        :label="item.label"
      ></el-option>
    </CSelect>
  </template>
  <template v-else-if="searchBoxItem.type === 'cascader'">
    <el-cascader
      class="form-item-base header-select"
      v-model="componentSearchForm[searchBoxItem.field]"
      :placeholder="searchBoxItem.placeholder || '请选择'"
      v-bind="handleBind(searchBoxItem)"
      :props="cascaderProps"
      @change="handleSelectChange"
      :clearable="searchBoxItem.clearable === false ? false : true"
      :options="getOptions(searchBoxItem)"
      :style="searchBoxItem.style"
      :disabled="searchBoxItem?.disabled ?? false"
    >
    </el-cascader>
  </template>
  <template v-else-if="searchBoxItem.type === 'datePicker'">
    <el-date-picker
      size="default"
      class="form-item-base"
      :type="searchBoxItem.dateType"
      v-model="componentSearchForm[searchBoxItem.field]"
      @change="handleInputChange"
      range-separator="-"
      :start-placeholder="`${searchBoxItem.label}开始`"
      :end-placeholder="`${searchBoxItem.label}截止`"
      :placeholder="searchBoxItem.placeholder || '请选择'"
      :value-format="searchBoxItem.format || 'YYYY/MM/DD'"
      :default-time="searchBoxItem.dateType == 'datetimerange' ? defaultTime2 : defaultTime1"
      :style="searchBoxItem.style"
      :unlink-panels="true"
      :disabled="searchBoxItem?.disabled ?? false"
    ></el-date-picker>
  </template>
  <template v-else-if="searchBoxItem.type === 'upload'">
    <div>
      <g-upload
        :class="{ 'disable-upload': searchBoxItem?.disabled }"
        :disabled="searchBoxItem?.disabled ?? false"
        :action="uploadFilePostUrlV3"
        :postParams="
          searchBoxItem?.fileConfig?.postParams
            ? searchBoxItem.fileConfig.postParams
            : {
                groupType: 'PCF_MODEL_INFO',
                scope: AllBizScopeEnum.PCF,
                needRename: false
              }
        "
        :inline="searchBoxItem?.fileConfig?.limit == 1"
        ref="uploadRef"
        :show-file-list="true"
        :limit="searchBoxItem?.fileConfig?.limit ? searchBoxItem.fileConfig.limit : 1"
        v-model:fileList="componentSearchForm[searchBoxItem.field]"
        :fileSizeLimit="20"
        @change="handleUploadChange"
        :accept="
          searchBoxItem?.fileConfig?.accept
            ? searchBoxItem.fileConfig.accept
            : '.jpg, .png, .jpeg, .pdf'
        "
      >
        <template #default="{ loading: btnLoading }">
          <el-button
            :loading="btnLoading"
            size="default"
            :disabled="searchBoxItem?.disabled ?? false"
            ><CIcon type="c-xian-shangchuan" class="g-mr4"></CIcon
            >{{
              componentSearchForm[searchBoxItem.field]?.length ? '重新上传' : '上传文件'
            }}</el-button
          >
        </template>
      </g-upload>
      <p class="g-font-12n3 g-mt4" v-if="!searchBoxItem?.disabled">
        {{
          searchBoxItem?.fileConfig?.tip
            ? searchBoxItem?.fileConfig?.tip
            : '支持 JPG、PNG、JPEG、PDF 格式文件，大小不超过20M'
        }}
      </p>
    </div>
  </template>
</template>

<script lang="ts" setup>
import { defineProps, defineEmits, reactive, ref, inject, unref } from 'vue';
import { CSelect } from '@/components/CSelect/index';
import { CStandardRadio, CStandardRadioGroup } from '@/components/CStandardRadio/index';
import { debounce } from 'lodash';
import { buildUUID } from '@/utils/uuid';
import * as selectOptions from '@/constants/enum';
import { uploadFilePostUrlV3 } from '@/apis/common/common';
import { GUpload } from '@/components/GUpload/index';
import { AllBizScopeEnum } from '@/commonModule/constants';
import { IFormSchema, IFormGroupInstance } from './form-detail';
import { useFormItem } from 'element-plus';

interface SearchBarItemProps {
  searchBoxItem: IFormSchema;
  searchForm: any;
}

const props = defineProps<SearchBarItemProps>();

const emits = defineEmits(['change']);
const { form } = useFormItem();
const { formConfig } = inject<IFormGroupInstance>('CFormDetailGroup', {});

const componentSearchForm = reactive(props.searchForm);
const cascaderProps = {
  emitPath: false
};
// 处理输入框改变事件
const handleInputChange = debounce(() => {
  handleSearchChange();
}, 600);

// select change
const handleSelectChange = (value: any, option: any) => {
  console.log('handleSelectChange', value, option);
  handleSearchChange();
};

const handleSearchChange = () => {
  if (props.searchBoxItem?.onFormChange) {
    props.searchBoxItem.onFormChange(componentSearchForm);
  } else {
    emits('change', componentSearchForm);
  }
};

const handleUploadChange = () => {
  // 如果有必填项才去重新校验
  let hasRequired = false;
  if (formConfig) {
    const { rules } = unref(formConfig);
    let ruleArr = rules[props.searchBoxItem.field];
    if (ruleArr && ruleArr.length) {
      hasRequired = ruleArr.some((item: any) => Reflect.has(item, 'required') && item.required);
    }
  }
  if (props.searchBoxItem?.required || hasRequired) {
    form?.validateField(props.searchBoxItem.field);
  }
  if (props.searchBoxItem?.onFormChange) {
    props.searchBoxItem.onFormChange(componentSearchForm);
  } else {
    emits('change', componentSearchForm);
  }
};

// 异步获取的选项列表
const asyncOptions = ref<any>({});

// 获取选项列表
const getOptions = (searchBoxItem: any) => {
  console.log('getOptions', searchBoxItem);
  if (searchBoxItem?.options?.length) {
    return searchBoxItem.options;
  } else if (searchBoxItem.loadData && searchBoxItem.uuid) {
    // 需要异步获取的
    return asyncOptions.value[searchBoxItem.uuid];
  } else if (searchBoxItem.fixedOption) {
    return (selectOptions as any)[searchBoxItem.fixedOption] || [];
  } else if (searchBoxItem.remoteMethod && searchBoxItem.uuid) {
    // 需要异步获取的
    return asyncOptions.value[searchBoxItem.uuid];
  }
  console.log('getOptions result end');
  return [];
};

// 远程获取选项数据
function handleRemoteMethod(query: string, searchBoxItem: any) {
  if (!searchBoxItem.remoteMethod) return;
  const result = searchBoxItem.remoteMethod(query);
  if (
    (typeof result === 'object' || typeof result === 'function') &&
    typeof result.then === 'function'
  ) {
    result.then((res: any) => {
      console.log('handleRemoteMethod res', res);
      asyncOptions.value[searchBoxItem.uuid as string] = res;
    });
  }
}

// 用于搜索select在筛选项出现时重新执行全量搜素，用于再次打开时能选择全部数据
function handleVisibleChange(val: any, searchBoxItem: any) {
  console.log('val', val, 'searchBoxItem', searchBoxItem);
  if (!searchBoxItem.remoteMethod) return;
  if (val) {
    handleRemoteMethod('', searchBoxItem);
  }
}

// 绑定参数
function handleBind(searchBoxItem: any) {
  const bindObj = {};
  if (searchBoxItem.remoteMethod) {
    Object.assign(bindObj, {
      remote: true,
      filterable: true,
      'remote-method': (query: string) => handleRemoteMethod(query, searchBoxItem),
      class: 'header-select--remote'
    });
  }

  // 是否自适应宽度
  if (searchBoxItem?.selectOption?.autoWidth) {
    Object.assign(bindObj, {
      autoWidth: searchBoxItem.selectOption.autoWidth
    });
    if (searchBoxItem?.selectOption?.defaultAutoWidth) {
      Object.assign(bindObj, {
        defaultAutoWidth: searchBoxItem.selectOption.defaultAutoWidth
      });
    }

    if (searchBoxItem?.selectOption?.maxAutoWidth) {
      Object.assign(bindObj, {
        maxAutoWidth: searchBoxItem.selectOption.maxAutoWidth
      });
    }
  }

  console.log('handleBind', bindObj, searchBoxItem);

  return bindObj;
}

// 处理异步选项获取
const preformAsyncOptions = (searchBoxItem: any) => {
  if (searchBoxItem.loadData) {
    searchBoxItem.uuid = buildUUID();
    asyncOptions.value[searchBoxItem.uuid as string] = [];
    const result = (searchBoxItem as any).loadData();
    if (
      (typeof result === 'object' || typeof result === 'function') &&
      typeof result.then === 'function'
    ) {
      result.then((res: any) => {
        console.log('loadData res', res);
        asyncOptions.value[searchBoxItem.uuid as string] = res;
      });
    }
  } else if (searchBoxItem.remoteMethod) {
    searchBoxItem.uuid = buildUUID();
    asyncOptions.value[searchBoxItem.uuid as string] = [];
    const result = (searchBoxItem as any).remoteMethod('');
    if (
      (typeof result === 'object' || typeof result === 'function') &&
      typeof result.then === 'function'
    ) {
      result.then((res: any) => {
        console.log('loadData res', res);
        asyncOptions.value[searchBoxItem.uuid as string] = res;
      });
    }
  }
};

// 处理异步选项获取
preformAsyncOptions(props.searchBoxItem);

const defaultTime2 = [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]; // '12:00:00', '08:00:00'
const defaultTime1 = [new Date(2000, 1, 1, 0, 0, 0)]; // '12:00:00', '08:00:00'
</script>

<style lang="scss" scoped>
.form-item-base {
  height: 32px !important;
  width: 280px;
  .el-input__wrapper {
    height: 32px;
  }
  .el-input__inner {
    height: 32px;
  }
}
:deep(.disable-upload) {
  .el-upload-list {
    margin-top: 0px;
  }
}
</style>
